package com.bsoft.gol.hbs.bbpmessagel.channel;
import com.bsoft.gol.hbs.bbpmessagel.entity.BaseJpushtoken;
import com.bsoft.gol.hbs.bbpmessagel.enums.RoleIdEnum;
import com.bsoft.gol.hbs.bbpmessagel.notification.bean.Alert;
import com.bsoft.gol.hbs.bbpmessagel.notification.event.JPushInstance;
import com.bsoft.gol.hbs.bbpmessagel.notification.event.NotificationEvent;
import com.bsoft.gol.hbs.bbpmessagel.notification.event.NotificationEvent.NotificateType;
import hcn.enums.InformTypeEnum;
import com.alibaba.fastjson.JSONObject;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import ctd.controller.exception.ControllerException;
import ctd.message.Message;
import ctd.net.rpc.json.JSONResponseBean;
import com.bsoft.gol.hbs.dao.JPushTokenDAO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import ssdev.bbp.message.channel.MessageChannel;

import java.lang.reflect.Array;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;

/**
 * @description:推送极光消息实现类
 * @author: zhengcb10708
 * @create: 2022-02-16 14:39
 **/
public class JPushServiceImpl implements MessageChannel {
    private final Logger logger = LoggerFactory.getLogger(JPushServiceImpl.class);
    @Autowired
    private JPushTokenDAO jPushTokenDAO;
    private LoadingCache<String, JPushInstance[]> jpushInstanceCache = CacheBuilder.newBuilder().build(new CacheLoader<String, JPushInstance[]>() {
        @Override
        public JPushInstance[] load(String tenantId) throws Exception {
            List<BaseJpushtoken> list = jPushTokenDAO.findTokens(tenantId);
            JPushInstance patientPush = null, doctorPush = null;
            if (list != null && !list.isEmpty()) {
                for (BaseJpushtoken token : list) {
                    String roleId = token.getRoleId();
                    if (RoleIdEnum.PATIENT.title().equals(roleId)) {
                        patientPush = new JPushInstance(token.getAppKey()==null?"":token.getAppKey().trim(), token.getMasterSecret()==null?"":token.getMasterSecret().trim(), "1".equals(token.getProduction()));
                    } else if (RoleIdEnum.DOCTOR.title().equals(roleId)) {
                        doctorPush = new JPushInstance(token.getAppKey()==null?"":token.getAppKey().trim(), token.getMasterSecret()==null?"":token.getMasterSecret().trim(), "1".equals(token.getProduction()));
                    }
                }
            }
            return new JPushInstance[]{patientPush, doctorPush};
        }
    });
    @Override
    public JSONResponseBean sendMessage(String jpushRegId, Message message) {
        JSONResponseBean response = new JSONResponseBean();
        Map<String, String> extras = message.getExtras();
        try {
            if(extras!=null&&extras.containsKey("diviceList")){
                NotificateType notificateType=this.getNotificateType(extras);
                NotificationEvent notificationEvent =new NotificationEvent(message.getTitle()==null?"您有一条新的消息通知":message.getTitle(),notificateType);
                Alert alert= new Alert(message.getTitle(),message.getContent(),notificationEvent.getNotificateType(),extras);
                //获取发送设备列表信息
                List<Map> deviceList  = JSONObject.parseArray(extras.get("deviceList"),Map.class);
                if(isEmpty(deviceList)){
                    logger.info("Device {} 信息为空"+deviceList);
                    return null;
                }
                for(Map deviceItem:deviceList){
                    /**deviceId：设备主键id   jpushRegId：用户在极光消息注册的id   badge：标识，数据类型为整型
                       onLine：0 下线 1上线   userId：用户id    tenantId:租户id   roleId:角色id
                     **/
                    int badgeFalg=isEmpty(deviceItem.get("badge"))==true?0:Integer.parseInt(deviceItem.get("badge").toString());
                    final int badge = badgeFalg <= 0 ? 1 : badgeFalg > 99 ? 99 : badgeFalg + 1;
                    if(isEmpty(deviceItem.get("jpushRegId"))){
                        logger.info("DeviceId {} ：jpushRegId为空，跳过发送极光消息", deviceItem.get("deviceId"));
                        continue;
                    }
                    final JPushInstance push = getPushInstance(alert.getNotificateType().getRoleId(), isEmpty(deviceItem.get("tenantId"))==true?"":deviceItem.get("tenantId").toString());
                    if (push == null) {
                        logger.error("Cannot get push instance for role: {}", alert.getNotificateType().getRoleId());
                        return null;
                    }
                    /*推送成功会返回消息id*/
                    long msgId = push.sendPushAll(alert, badge, deviceItem.get("jpushRegId").toString());
                    if(msgId>0){
                        response.setCode(200);
                    }else {
                        response.setCode(400);
                        response.setMsg("极光消息发送失败");
                    }
                }

            }
        } catch (Exception e) {
            e.printStackTrace();
            response.setCode(400);
            response.setMsg(String.format("极光消息发送失败 [%s]", e));
        }
        return response;
    }
     //组装 NotificateType
     private NotificationEvent.NotificateType getNotificateType(Map<String, String> extras){
         NotificationEvent.NotificateType notificateType=NotificationEvent.NotificateType.patientAppControl;
         notificateType.setRoleId(extras.get("eventRoleId"));
         notificateType.setGroup(extras.get("eventGroup"));
         notificateType.setTypeCode(extras.get("eventTypeCode"));
         notificateType.setPersistent("true".equals(extras.get("eventPersistent"))?true:false);
         notificateType.setOperationable("true".equals(extras.get("eventOperationable"))?true:false);
         notificateType.setMessageRegion(extras.get("eventMessageRegion")==null?null:InformTypeEnum.valueOf(extras.get("eventMessageRegion")));
         return notificateType;
     }
    /**
     * @param roleId
     * @return
     */
    private JPushInstance getPushInstance(String roleId, String tenantId) throws ControllerException {
        JPushInstance[] instances;
        try {
            instances = jpushInstanceCache.get(tenantId);
        } catch (ExecutionException e) {
            throw new ControllerException(e);
        }
        if (RoleIdEnum.PATIENT.title().equals(roleId)) {
            return instances[0];
        } else if (RoleIdEnum.DOCTOR.title().equals(roleId)) {
            return instances[1];
        }
        return null;
    }

    //校验空值
    private static boolean isEmpty(Object obj) {
        if (obj == null) {
            return true;
        }
        if (obj instanceof CharSequence) {
            return ((CharSequence) obj).length() == 0;
        }
        if (obj instanceof Collection) {
            return ((Collection<?>) obj).isEmpty();
        }
        if (obj instanceof Map) {
            return ((Map<?, ?>) obj).isEmpty();
        }
        if (obj.getClass().isArray()) {
            return Array.getLength(obj) == 0;
        }
        return false;
    }

}
